package com.bkitmobile.kesu.appengine.mobile.server;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;

import org.json.*;
import com.bkitmobile.kesu.appengine.storingdata.server.*;
import com.bkitmobile.kesu.appengine.storingdata.server.entity.CommentsLocation;
import com.bkitmobile.kesu.appengine.storingdata.server.entity.InviteUser;
import com.bkitmobile.kesu.appengine.storingdata.server.entity.Place;
import com.bkitmobile.kesu.appengine.storingdata.server.entity.LocationData;
import com.bkitmobile.kesu.appengine.storingdata.server.entity.Message;
import com.bkitmobile.kesu.appengine.storingdata.server.entity.User;
import com.bkitmobile.kesu.appengine.storingdata.server.entity.UserConfig;
import com.bkitmobile.kesu.appengine.storingdata.server.entity.UserLocationData;
import com.google.appengine.api.datastore.Blob;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.repackaged.com.google.common.util.Base64;
import com.google.appengine.repackaged.com.google.common.util.Base64DecoderException;
public class Responses {
	
	/**
	 * update list friends
	 * @param username 
	 * @return
	 */
	public static String UpdateFriendsList(String username)
	{
		DataStoreManager db = new DataStoreManager();
		User user = db.getUser(username);
		UserLocationData uData = db.getUserLocationData(username);
        List fList = db.getFriendsList(user);
        List wList = db.getWaitingList(user);
        List<InviteUser> wList1 = db.getCommentInvite(user);
        List<User> mList = db.getSee24hList(uData);
        List<User> viewInviList = db.getViewInviList(user);
        JSONObject obj = new JSONObject();
        try {
        obj.put("fList", convertfListToString(fList,db,user));
        obj.put("waitList", convertwListToString(wList));
        obj.put("isWaitList", convertwIListToString(wList1));
        obj.put("24hList", view24h(mList));
        obj.put("viewInviList", inviList(viewInviList));
        obj.put("messageList", getMessageList(user,db));
        obj.put("config", getConfig(user,db));
        } catch (JSONException e)
        {
        	
        }
        return obj.toString();
	}
	/**
	 * get list message
	 * @param u
	 * @param db
	 * @return messages send when user log out
	 */
	private static String getMessageList(User u,DataStoreManager db) {
        JSONStringer js = new JSONStringer();
        List<Message> listMessage = new ArrayList<Message>();
        Object[] lsKey = u.getMessages().toArray();
        for (int i = 0 ; i < lsKey.length ; i++)
        {
        	try {
        		Message message = db.getMessage((Key)lsKey[i]);
            	listMessage.add(message);
        		db.deleteMessage((Key)lsKey[i]);
        	} catch (Exception e)
        	{
        		
        	}
        }
        if (listMessage.size()==0) return null;
        try{
	        js.array();
	        for (int i = 0 ; i < listMessage.size() ; i++)
	        {
	        	String message = "";
	        	for (int j = 0 ; j < listMessage.get(i).getMessage().size();j++)
	        	{
	        		message += listMessage.get(i).getMessage().get(j).getValue()+"\n";
	        	}
	        	
	        	js.object().key("sender").value(listMessage.get(i).getSender())
	        				.key("msg").value(message).endObject();
	        }
	        js.endArray();
	        u.setMessages(null);
	        db.updateUser(u);
        } catch (JSONException e)
        {
        	return null;
        }
		return js.toString();
	}
	/**
	 * update location
	 * @param username
	 * @param longitude
	 * @param latitude
	 * @return list Places around user
	 */
	public static String getFrAvatar(String uFrom,String uDest){
		DataStoreManager db = new DataStoreManager();
		User uFr = db.getUser(uFrom);
		User uDst = db.getUser(uDest);
		if (uFr.getFriendsList().contains(uDst.getKey())){
			byte[] bytes = uDst.getAvatar().getBytes();
			String resp = Base64.encode(bytes);
			return resp;
		} else {
			return null;
		}
	}
	public static String UpdateLocationResp(String username
			,String longitude,String latitude)
	{
		 DataStoreManager db = new DataStoreManager();
         User u = db.getUser(username);  
         double lat = Double.parseDouble(latitude);
         double lng = Double.parseDouble(longitude);
         u.setCurrentLatitude(lat);
         u.setCurrentLongitude(lng);
         db.updateUser(u);
         
         DataStoreManager db1 = new DataStoreManager();
         UserLocationData lData = db1.getUserLocationData(username);
         lData.addNewLocation(Double.parseDouble(latitude)
        		 , Double.parseDouble(longitude), null,false);
         
         db1.UpdateLocationData(lData);
         UserConfig uConfig = db.getUserConfig(username);
         if (uConfig.getAlertPlace() == UserConfig.SILENT) return null;
         List<Place> result = db.listPlaceAlert(lat, lng, uConfig);
         if (result == null) return null;
         JSONObject obj = new JSONObject();
         try {
             obj.put("id", "alert");
             JSONStringer js = new JSONStringer();
        	 js.array();
        	 for (Place tmp:result)
        	 {
        		js.object()
        			 	.key("name").value(tmp.getName())
        			 	.key("lat").value(tmp.getLattitude())
        			 	.key("lng").value(tmp.getLongtitude())
        			 	.key("addr").value(tmp.getAddress())
        			 	.key("type").value(tmp.getType())
        			 	.endObject();
        	 }
        	 js.endArray();
        	 obj.put("places", js.toString());
         } catch (JSONException e)
         {
        	 
         }
         return obj.toString();
	}
	/**
	 * accept invite
	 * @param uFrom user who accept
	 * @param uDest user who invite
	 */
	public static void acceptInviteResp(String uFrom, String uDest)
	{
		DataStoreManager db = new DataStoreManager();
		User uFr = db.getUser(uFrom);
		User uDst = db.getUser(uDest);
		db.acceptInvite(uFr, uDst);
	}
	/**
	 * deny invite
	 * @param uFrom user who deny
	 * @param uDest user who invite
	 */
	public static void denyInviteResp(String uFrom,String uDest)
	{
		DataStoreManager db = new DataStoreManager();
		User uFr = db.getUser(uFrom);
		User uDst = db.getUser(uDest);
		db.denyInvite(uFr, uDst);
	}
	/**
	 * add friend
	 * @param uFrom user who invite
	 * @param uDest user who invited
	 * @param cmt 
	 * @return 1 if success, -1 if unsuccess
	 */
	public static int addFriendResp(String uFrom,String uDest,String cmt)
	{
		DataStoreManager db = new DataStoreManager();
		User uD = null;
		try{
			uD = db.getUser(uDest);
		} catch (Exception e)
		{
			return -1;
		}
		User uF = db.getUser(uFrom);
		Object[] friendList = uF.getFriendsList().toArray();
		for (int i = 0 ; i < friendList.length ; i++)
		{
			if (friendList[i].equals(uD.getKey()))
					return -1;
		}
		Object[] waitingList = uF.getWaitingAccept().toArray();
		for (int i = 0 ; i < waitingList.length ; i++)
		{
			if (waitingList[i].equals(uD.getKey()))
					return -1;
		}
		Object[] isWaitingList = uF.getIsWaitingAccept().toArray();
		for (int i = 0 ; i < isWaitingList.length ; i++)
		{
			if (isWaitingList[i].equals(uD.getKey()))
			{
				db.acceptInvite(uF, uD);
				return -1;
			}
		}
		
		try{
		db.inviteUser(uF, uD,cmt);
		} catch (Exception e)
		{
			return -1;
		}
		return 1;
	}
	/**
	 * do login
	 * @param req params 
	 * @return result login
	 */
	public static String loginResp(HttpServletRequest req)
	{
		String result = null;
		String username = req.getParameter("username");
		String password = req.getParameter("password");
		String invi = req.getParameter("invisible");
		boolean isInvisible = false;
		if (invi.equals("invisible")) isInvisible = true;
		DataStoreManager db = new DataStoreManager();
		boolean isLogined = false;
		JSONObject obj = new JSONObject();
		try{
			isLogined = db.isLogined(username);
		} catch (NullPointerException e)
		{
			try {
				obj.put("result", "Username or password incorrect");
			} catch (JSONException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			return obj.toString();
		}
		int success = db.doLogin(username, password,!isInvisible);
		if (success == 1) 
		{
			
			User user = db.getUser(username);
			UserLocationData uData = db.getUserLocationData(username);
	        List fList = db.getFriendsList(user);
	        List wList = db.getWaitingList(user);
	        List<InviteUser> wList1 = db.getCommentInvite(user);
	        List<User> mList = db.getSee24hList(uData);
	        List<User> viewInviList = db.getViewInviList(user);
	        try {
	        	obj.put("result", "success");
	        obj.put("fList", convertfListToString(fList,db,user));
	        obj.put("waitList", convertwListToString(wList));
	        obj.put("isWaitList", convertwIListToString(wList1));
	        obj.put("24hList", view24h(mList));
	        obj.put("viewInviList", inviList(viewInviList));
	        obj.put("messageList", getMessageList(user,db));
	        obj.put("config", getConfig(user,db));
	        } catch (JSONException e)
	        {
	        	
	        }
	        result = obj.toString();
			if (isLogined) 
			{
				return "<save>"+result;
			}
		}
		else if (success == -1) 
			{
				try {
					obj.put("result", "Username or password incorrect");
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				result = obj.toString();
			}
		return result;
	}
	/**
	 * get user's configs
	 * @param user 
	 * @param db
	 * @return user's configs
	 */
	public static String getConfig(User user,DataStoreManager db){
		JSONObject jObject = new JSONObject();
		UserConfig uConfig = db.getUserConfig(user.getId());
		try {
			jObject.put("alertChat", uConfig.getAlertChat());
			jObject.put("alertPlace", uConfig.getAlertPlace());
			jObject.put("loadAround", uConfig.isLoadAround());
			jObject.put("loadFavorite", uConfig.isLoadFavorite());
			jObject.put("loadMyPlace", uConfig.isLoadMyPlace());
			JSONStringer js = new JSONStringer();
			js.array();
			for (int i = 0 ; i < uConfig.getListType().size() ; i++)
			{
				js.object().key("type").value(uConfig.getListType().get(i)).endObject();
			}
			js.endArray();
			jObject.put("listType", js.toString());
		} catch (JSONException e)
		{
			e.printStackTrace();
		}
		return jObject.toString();
	}
	/**
	 * 
	 * @param username
	 * @return
	 */
	public static String get24hListResp(String username) {
		DataStoreManager db = new DataStoreManager();
		UserLocationData uData = db.getUserLocationData(username);
		List<User> mList = db.getSee24hList(uData);
		String result = "success"+view24h(mList);
		return result;
	}
	/**
	 * 
	 * @param lsUser
	 * @return
	 */
	private static String view24h(List<User> lsUser)
	{
		JSONStringer js = new JSONStringer();
		try {
			js.array();
			for (int i = 0; i < lsUser.size(); i++){
				js.object().key("user").value(lsUser.get(i).getId()).endObject();
			}
			js.endArray();
		} catch (Exception e)
		{
			
		}
		return js.toString();
	}
	/**
	 * 
	 * @param lsUser
	 * @return
	 */
	private static String inviList(List<User> lsUser)
	{
		JSONStringer js = new JSONStringer();
		try {
			js.array();
			for (int i = 0; i < lsUser.size(); i++){
				js.object().key("user")
				.value(lsUser.get(i).getId()).endObject();
			}
			js.endArray();
		} catch (JSONException e)
		{
			
		}
		return js.toString();
	}
	/**
	 * 
	 * @param username
	 * @return
	 */
	public static String getInviList(String username) {
		DataStoreManager db = new DataStoreManager();
		User u = db.getUser(username);
		List<User> lsViewInvi = db.getViewInviList(u);
		String result = "success"+inviList(lsViewInvi);
		return result;
	}
	/**
	 * 
	 * @param ls
	 * @return
	 */
	private static String convertwIListToString(List<InviteUser> ls)
	{
		JSONStringer js = new JSONStringer();
		try{
			int lsSize = ls.size();
			js.array();
			for (int i = 0 ; i < lsSize ; i++)
			{
				js.object().key("user").value(ls.get(i).getIdFrom())
							.key("cmt").value(ls.get(i).getComment()).endObject();
			}
			js.endArray();
		} catch (Exception e)
		{
			
		}
		return js.toString();
	}
	/**
	 * 
	 * @param after
	 * @param before
	 * @return
	 */
	private static String getTimeAgo(long after,long before)
	{
		long ago = after - before;
		String time = "";
		int year = (int) (ago / (1000*3600*24*365.25));
		int month = (int) (ago / (1000*3600*24*30));
		int day = (int) (ago / (1000*3600*24));
		int hour = (int) (ago / (1000*3600));
		int min = (int) (ago / (1000*60));
		int sec = (int) (ago / (1000));

		if (year >1 ) time = year + " years ago";
		else if (year == 1) time = year + " year ago";
		else if (month > 1) time = month + " months ago";
		else if (month == 1) time = month + " month ago";
		else if (day > 1) time = day + " days ago";
		else if (day == 1) time = day + " day ago";
		else if (hour > 1) time = hour + " hours ago";
		else if (hour == 1) time = hour + " hour ago";
		else if (min > 1) time = min + " mins ago";
		else if (min == 1) time = min + " min ago";
		else if (sec > 1) time = sec + " seconds ago";
		else if (sec == 1) time = sec + " second ago";
		return time;
	}
	/**
	 * 
	 * @param ls
	 * @param db
	 * @param user
	 * @return
	 */
	private static String convertfListToString(List<User> ls
			,DataStoreManager db,User user)
	{
		int lsSize = ls.size();
		Set<Key> viewPermisions = user.getViewInvisiblePermision();
		Set<Key> manageUser = user.getManageUser();
		long currentDate = new Date().getTime();
		JSONStringer js = new JSONStringer();
		try {
			js.array();
			for (int i = 0 ; i < lsSize ; i++)
			{
				boolean state = (ls.get(i).isAvailable() 
						||viewPermisions.contains(ls.get(i).getKey())
						||manageUser.contains(ls.get(i).getKey()))
							&& ls.get(i).isLoggedin();
				String str = null;
				try {
					str = Base64.encode(ls.get(i).getAvatar().getBytes());
				} catch (Exception e){
					
				}
				js.object().key("user").value(ls.get(i).getId())
					.key("status").value(ls.get(i).getStatus())
					.key("state").value((state?"online" : "offline"))
					.key("img").value(str)
					.endObject();
		}
			js.endArray();
		}
		catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return js.toString();
	}
	/**
	 * 
	 * @param ls
	 * @return
	 */
	private static String convertwListToString(List<User> ls)
	{
		JSONStringer js = new JSONStringer();
		try {
			js.array();
			int lsSize = ls.size();
			for (int i = 0 ; i < lsSize ; i++)
			{
				js.object().key("user").value(ls.get(i).getId()).endObject();
			}
			js.endArray();
		} catch (Exception e)
		{
			
		}
		
		return js.toString();
	}
	/**
	 * get list location near user and friends
	 * @param username 
	 * @param lat
	 * @param lng
	 * @return
	 */
	public static String locationsResp(String username,double lat,double lng)
	{
		DataStoreManager db = new DataStoreManager();
		UserConfig uConfig = db.getUserConfig(username);
		JSONObject obj = new JSONObject();
		try {
			obj.put("fLocation", friendLocationResp(username,db));
			obj.put("pLocation", placeLocationResp(uConfig,db,lat,lng)); 
			obj.put("isNear",uConfig.isLoadAround());
			obj.put("isFavorite", uConfig.isLoadFavorite());
		} catch (JSONException e)
		{
			
		}
		return obj.toString();
	}
	/**
	 * get list places
	 * @param uConfig
	 * @param db
	 * @param lat
	 * @param lng
	 * @return
	 */
	private static String placeLocationResp(UserConfig uConfig,DataStoreManager db,double lat,double lng)
	{
		JSONStringer js = new JSONStringer();
		List<Place> lsPlaces = new ArrayList<Place>();
		User u = db.getUser(uConfig.getUsername());
		List<Place> lsPersonal = db.filterMyLocation(u);
		List<Place> lsAround = null;
		List<Place> lsFavorite = null;
		
		if (uConfig.isLoadAround())
		{
			lsAround = db.getPlaceNear(lng, lat,Place.DISTANCE_LOAD_MAP);
			for (Place tmp:lsAround)
				lsPlaces.add(tmp);
		}
		if (uConfig.isLoadFavorite())
		{	
			lsFavorite = db.filterMyFavoritePlace(u);
			for (Place tmp:lsFavorite)
			{
				if (!lsPlaces.contains(tmp))
					lsPlaces.add(tmp);
			}
		}
		
		try {
			js.array();
			if (lsPlaces != null)
				for (int i = 0 ; i < lsPlaces.size() ; i++)
				{
					if (uConfig.isLoadAround() && uConfig.isLoadFavorite())
					{
						int load = 0;
						if (lsAround.contains(lsPlaces.get(i))) load += 1;
						if (lsFavorite.contains(lsPlaces.get(i))) load += 2;
						js.object().key("lat").value(lsPlaces.get(i).getLattitude())
						.key("lng").value(lsPlaces.get(i).getLongtitude())
						.key("name").value(lsPlaces.get(i).getName())
						.key("type").value(lsPlaces.get(i).getType())
						.key("load").value(load).endObject();
					}
					else js.object().key("lat").value(lsPlaces.get(i).getLattitude())
					.key("lng").value(lsPlaces.get(i).getLongtitude())
					.key("name").value(lsPlaces.get(i).getName())
					.key("type").value(lsPlaces.get(i).getType()).endObject();
				}
			if (lsPersonal != null)
				for (int i = 0 ; i < lsPersonal.size() ; i++)
				{
					js.object().key("lat").value(lsPersonal.get(i).getLattitude())
								.key("lng").value(lsPersonal.get(i).getLongtitude())
								.key("name").value(lsPersonal.get(i).getName())
								.key("type").value(lsPersonal.get(i).getType()).endObject();
				}
			js.endArray();
		} catch (JSONException e)
		{
			
		}
		return js.toString();
	}
	/**
	 * get list friend
	 * @param username
	 * @param db
	 * @return
	 */
	private static String friendLocationResp(String username,DataStoreManager db)
	{	
		User user = db.getUser(username);
		Set<Key> viewPermisions = user.getViewInvisiblePermision();
		Set<Key> manageUser = user.getManageUser();
		List<User> fList = db.getFriendsList(user);
		JSONStringer js = new JSONStringer();
		long currentDate = new Date().getTime();
		try{
			js.array();
			for (int i = 0 ; i < fList.size() ; i++)
			{
				boolean state = (fList.get(i).isAvailable() 
						||viewPermisions.contains(fList.get(i).getKey())
						||manageUser.contains(fList.get(i).getKey()))
							&& fList.get(i).isLoggedin();
				if (state)
				{
					UserLocationData uld = db.getUserLocationData(fList.get(i).getId());
					long lastUpdate = uld.getLocationData().get(0).getDate().getTime();
					long lastUpdateStatus = uld.getCurrentStatus().getDate().getTime();
					String timeUpdateStatus = getTimeAgo(currentDate,lastUpdateStatus);
					double latitude = fList.get(i).getCurrentLatitude();
					double longitude = fList.get(i).getCurrentLongitude();
					double slongitude = uld.getCurrentStatus().getLongitude();
					double slatitude = uld.getCurrentStatus().getLatitude();
					String timeUpdate = getTimeAgo(currentDate,lastUpdate);
					js.object()
						.key("user").value(fList.get(i).getId())
						.key("long").value(longitude)
						.key("lat").value(latitude)
						.key("time").value(timeUpdate)
						.key("slong").value(slongitude)
						.key("slat").value(slatitude)
						.key("stime").value(timeUpdateStatus)
					.endObject();
				}
			}
			js.endArray();
		}	catch (JSONException e)
		{
			
		}
		return js.toString();
	}
	/**
	 * regiter
	 * @param username
	 * @param password
	 * @param firstname
	 * @param lastname
	 * @param birthday
	 * @param email
	 * @param sex
	 * @param isFree
	 * @return
	 */
	public static String regResp(String username,String password,String firstname,
			String lastname,String birthday,String email,boolean sex,boolean isFree)
	{
		int res;
		User user = new User(username, password, 
				firstname, lastname, "", 
			birthday, email, 
			"", "", "", sex, "", 
			0, 0, false, false,new Date());

		DataStoreManager db = new DataStoreManager();
		res = db.createUser(user);
		return res ==1 ? "success":"exist";
	}
	/**
	 * change status
	 * @param username
	 * @param status
	 * @param longitude
	 * @param latitude
	 */
	public static void changeStatus(String username, String status
			,double longitude,double latitude) {
		// TODO Auto-generated method stub
		DataStoreManager db = new DataStoreManager();
		User user = db.getUser(username);
		UserLocationData uld = db.getUserLocationData(username);
		uld.addNewLocation(latitude, longitude, status, false);
		user.setStatus(status);
		db.updateUser(user);
		db.UpdateLocationData(uld);
	}
	/**
	 * get profile
	 * @param username
	 * @return
	 */
	public static String getMyProfile(String username) {
		// TODO Auto-generated method stub
		DataStoreManager db = new DataStoreManager();
		User user = db.getUser(username);
		JSONObject obj = new JSONObject();
		try {
			obj.put("fName", user.getFirstName());
			obj.put("lName", user.getLastName());
			obj.put("sex", (user.getSex()?"male":"female"));
			obj.put("bDay", user.getBirthDay());
			obj.put("email", user.getEmail());
			try {
				String str = Base64.encode(user.getAvatar().getBytes());
				obj.put("avatar", str);
			} catch (Exception e){
				
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return obj.toString();
	}
	/**
	 * update profile
	 * @param username
	 * @param fname
	 * @param lname
	 * @param sex
	 * @param bdate
	 * @param email
	 * @return
	 */
	public static String updateMyProfile(String username, String fname,
			String lname, String sex, String bdate, String email,String img) {
		// TODO Auto-generated method stub
		String result = "success";
		DataStoreManager db = new DataStoreManager();
		User user = db.getUser(username);
		user.setFirstName(fname);
		user.setLastName(lname);
		user.setSex(sex.equals("male"));
		user.setEmail(email);
		user.setBirthDay(bdate);
		// get img from string
		//byte[] bytes = Base64.
		byte[] bytes;
		try {
			bytes = Base64.decode(img);
		} catch (Base64DecoderException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			bytes = null;
		}
		Blob imageBlob = new Blob(bytes);
		user.setAvatar(imageBlob);
		db.updateUser(user);
		return result;
	}
	/**
	 * get friend profile
	 * @param username
	 * @param friend
	 * @return
	 */
	public static String getFriendProfile(String username, String friend) {
		DataStoreManager db = new DataStoreManager();
		User user = db.getUser(friend);
		JSONObject obj = new JSONObject();
		try {
			if(user != null){	
				obj.put("result", "success");
				obj.put("fName", user.getFirstName());
				obj.put("lName", user.getLastName());
				obj.put("sex", user.getSex());
				obj.put("bDay", user.getBirthDay());
				obj.put("email", user.getEmail());
				return obj.toString();
			}
			obj.put("result", "Can not find out " + friend);
		} catch (Exception e)
		{
			
		}
		return obj.toString();
	}
	/**
	 * 
	 * @param username
	 * @param person
	 * @return
	 */
	public static String allowFollow(String username, String person) {
		// TODO Auto-generated method stub
		DataStoreManager db = new DataStoreManager();
		User user = db.getUser(username);
		User friend = db.getUser(person);
		Key keyUser = KeyFactory.createKey(User.class.getSimpleName(), username);
		Key keyFriend = KeyFactory.createKey(User.class.getSimpleName(), person);
		
		user.getUserViewInvisible().add(keyFriend);
		friend.getViewInvisiblePermision().add(keyUser);
		db.updateUser(user);
		db.updateUser(friend);
		
		return "success";
	}
	/**
	 * 
	 * @param username
	 * @param person
	 * @return
	 */
	public static String disallowFollow(String username, String person) {
		// TODO Auto-generated method stub
		DataStoreManager db = new DataStoreManager();
		User user = db.getUser(username);
		User friend = db.getUser(person);
		Key keyUser = KeyFactory.createKey(User.class.getSimpleName(), username);
		Key keyFriend = KeyFactory.createKey(User.class.getSimpleName(), person);
		
		user.getUserViewInvisible().remove(keyFriend);
		friend.getViewInvisiblePermision().remove(keyUser);
		db.updateUser(user);
		db.updateUser(friend);
		
		return "success";
	}
	/**
	 * 
	 * @param username
	 * @param person
	 * @return
	 */
	public static String allowSee24(String username, String person) {
		DataStoreManager db = new DataStoreManager();
		UserLocationData uld = db.getUserLocationData(username);
		User user = db.getUser(person);
		Key userKey = KeyFactory.createKey(User.class.getSimpleName(), username);
		Key personKey = KeyFactory.createKey(User.class.getSimpleName(), person);
		uld.getUsersView().add(personKey);
		user.getManageUser().add(userKey);
		db.updateUser(user);
		db.UpdateLocationData(uld);
		return "success";
	}
	/**
	 * 
	 * @param username
	 * @param person
	 * @return
	 */
	public static String disallowSee24(String username, String person) {
		DataStoreManager db = new DataStoreManager();
		UserLocationData uld = db.getUserLocationData(username);
		Key key = KeyFactory.createKey(User.class.getSimpleName(), person);
		uld.getUsersView().remove(key);
		
		User user = db.getUser(person);
		Key uKey = KeyFactory.createKey(User.class.getSimpleName(), username);
		user.getManageUser().remove(uKey);
		db.updateUser(user);
		db.UpdateLocationData(uld);
		return "success";
	}
	/**
	 * 
	 * @param username
	 * @param pass
	 * @return
	 */
	public static String changePassword(String username,String pass) {
		// TODO Auto-generated method stub
		DataStoreManager db = new DataStoreManager();
		User u = db.getUser(username);
		try {
			u.setPassword(MD5.convert(pass));
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return "fail";
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return "fail";
		}
		db.updateUser(u);
		return "success";
	}
	/**
	 * get list location in 24h
	 * @param userDest
	 * @param userFrom
	 * @return list location
	 */
	public static String get24hPosition(String userDest,String userFrom) {
		// TODO Auto-generated method stub
		DataStoreManager db = new DataStoreManager();
        UserLocationData uld = db.getUserLocationData(userDest);
        Key keyFrom = db.getUKey(userFrom);
        JSONObject obj = new JSONObject();
        try {
	        if (!uld.getUsersView().contains(keyFrom))
	        {
	        	obj.put("result", "Can't view list "+userDest+"'s location");
	        	return obj.toString();
	        } else obj.put("result", "success");
	        List<LocationData> locations = uld.getLocationData();
	        JSONStringer js = new JSONStringer();
	        js.array();
	        for (int i = 0 ; i < locations.size() ; i++)
	        {
	        	if (i != 0&&locations.get(i).isFirst()) continue;
                String time = getTimeAgo(new Date().getTime(), locations.get(i).getDate().getTime());
                     js.object().key("long").value(locations.get(i).getLongitude())
                                .key("lat").value(locations.get(i).getLatitude())
                                .key("time").value(time).endObject();
	        }
            js.endArray();
            obj.put("listLocation", js.toString());
        } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
        }
        return obj.toString();
	}
	/**
	 * 
	 * @param user
	 * @param lat
	 * @param lng
	 * @return
	 */
	public static String getPlaceInfoResp(String user,String lat, String lng) {
		// TODO Auto-generated method stub
		DataStoreManager db = new DataStoreManager();
		Key k = db.getPlaceKey(lng+""+lat);
		Place loc = db.getPlace(k);
		User u = db.getUser(user);
		JSONObject obj = new JSONObject();
		try {
			obj.put("like", u.getFavoritePlace().contains(loc.getKey()));
			obj.put("addr", loc.getAddress());
			obj.put("info", loc.getInfo());
			obj.put("userCreate",db.getUser(loc.getUserCreate()).getId());
			obj.put("cmt", getPlaceCmt(loc));
		} catch (JSONException e)
		{
			
		}
		return obj.toString();
	}
	/**
	 * get place comment
	 * @param loc
	 * @return
	 */
	private static String getPlaceCmt(Place loc){
		List<CommentsLocation> listCmt = loc.getListCmt();
		JSONStringer js = new JSONStringer();
		try {
			js.array();
			if (listCmt != null)
				for (int i = 0 ; i < listCmt.size() ; i++)
				{
					String time = getTimeAgo(new Date().getTime(), listCmt.get(i).getDate().getTime());
					js.object().key("user").value(listCmt.get(i).getIdUser())
							.key("cmt").value(listCmt.get(i).getComment())
							.key("time").value(time).endObject();
				}
			js.endArray();
		} catch (JSONException e)
		{
			
		}
		return js.toString();
	}
	/**
	 * get filter place
	 * @param username
	 * @param lat
	 * @param lng
	 * @param filter
	 * @return
	 */
	public static String getFilterPlace(String username,double lat,double lng,String filter)
	{
		DataStoreManager db = new DataStoreManager();
		List<Place> result = null;
		if (filter.equals("near")) 
			result = db.getPlaceNear(lng, lat, Place.DISTANCE_LOAD_MAP);
		else {
			User u = db.getUser(username);
			result = db.filterMyFavoritePlace(u);
		}
		JSONStringer js = new JSONStringer();
		try {
			js.array();
			if (result != null)
				for (int i = 0 ; i < result.size() ; i++)
				{
					js.object().key("lat").value(result.get(i).getLattitude())
								.key("lng").value(result.get(i).getLongtitude())
								.key("name").value(result.get(i).getName())
								.key("type").value(result.get(i).getType()).endObject();
				}
			js.endArray();
		} catch (JSONException e)
		{
			
		}
		return js.toString();
	}
	/**
	 * find places near user
	 * @param name place's name
	 * @param type place's type
	 * @param distance max distance between user and place
	 * @param lat latitude of user
	 * @param lng longitude of user
	 * @return list of places
	 */
	public static String search(String name,String type,double distance,double lat,double lng)
	{
		DataStoreManager db = new DataStoreManager();
		JSONStringer js = new JSONStringer();
		
		List<Place> lsSearch = db.search(lat, lng, type, name, distance);
		try {
			js.array();
			if (lsSearch != null) for (int i = 0 ; i < lsSearch.size() ; i++)
			{
				js.object().key("type").value(lsSearch.get(i).getType())
							.key("name").value(lsSearch.get(i).getName())
							.key("addr").value(lsSearch.get(i).getAddress())
							.key("lat").value(lsSearch.get(i).getLattitude())
							.key("lng").value(lsSearch.get(i).getLongtitude()).endObject();
			}
			js.endArray();
		} catch (JSONException e)
		{
			e.printStackTrace();
		}
		return js.toString();
	}
}
